package cn.stylefeng.guns.modular.gridsystem.modbus;

import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.modular.gridsystem.entity.BizDevice;
import cn.stylefeng.guns.modular.gridsystem.entity.BizException;
import cn.stylefeng.guns.modular.gridsystem.entity.BizExceptionLog;
import cn.stylefeng.guns.modular.gridsystem.entity.BizGatewayChannel;
import cn.stylefeng.guns.modular.gridsystem.service.BizDeviceService;
import cn.stylefeng.guns.modular.gridsystem.service.BizExceptionLogService;
import cn.stylefeng.guns.modular.gridsystem.service.BizExceptionService;
import cn.stylefeng.guns.modular.gridsystem.service.BizGatewayChannelService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.serotonin.modbus4j.BasicProcessImage;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;
import java.util.List;

//@EnableScheduling
//@Component
public class ModbusDataUpdater {


    @Resource
    private BasicProcessImage basicProcessImage;

    @Resource
    private BizExceptionLogService bizExceptionLogService;

    @Resource
    private BizExceptionService bizExceptionService;

    @Resource
    private BizDeviceService bizDeviceService;

    @Resource
    private BizGatewayChannelService bizGatewayChannelService;


    @Scheduled(fixedRate = 1000 * 2)
    private void updateExceptionLog() {

        QueryWrapper<BizExceptionLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("exception_time");
        queryWrapper.last("limit 1");
        BizExceptionLog bizExceptionLog = bizExceptionLogService.getOne(queryWrapper);
        if (bizExceptionLog != null) {
            String gatewayCode = bizExceptionLog.getGatewayCode();
            BizException bizException = bizExceptionService.getById(bizExceptionLog.getExceptionId());

            if (bizException != null) {
                ModbusDeviceLog log = new ModbusDeviceLog();
                log.setLogId(bizExceptionLog.getId());
                try {
                    BizDevice bizDevice = bizDeviceService.getById(bizException.getDeviceId());
                    if (bizDevice != null) {
                        log.setDeviceId(Integer.parseInt(bizDevice.getDeviceName()));//设备编号
                    }
                } catch (Exception e) { //设备编号为非数字时抛异常设置为0
                    log.setDeviceId(0);
                }
                try {
                    log.setGatewayId(Integer.parseInt(gatewayCode));//网关编号为非数字时抛异常设置为0
                }catch (Exception e){
                    log.setGatewayId(0);//网关编号
                }
                log.setErrorId(Integer.parseInt(bizExceptionLog.getAccessToken()));//17003  accessToken
                if(ObjectUtil.isNotNull(bizExceptionLog.getExceptionTime())){
                    log.setUpdateDate((int) (bizExceptionLog.getExceptionTime().getTime() / 1000)); //故障时间
                }
                final List<Short> encode = log.encode();
                for (int i = 0; i < encode.size(); i++) {
                    short value = encode.get(i);
                    basicProcessImage.setHoldingRegister(i + log.getOffset(), value);
                }
            }
        }

    }

    @Scheduled(fixedRate = 1000 * 2)
    private void updateDeviceStatus() {
        List<BizGatewayChannel> list = bizGatewayChannelService.list();
        boolean[] booleans = new boolean[list.size()];
        for (int i = 0; i < list.size(); i++) {
            booleans[i] = list.get(i).getStatus() == 1;
        }
        ModbusDeviceStatus status = new ModbusDeviceStatus();
        status.setGatewayStatus(booleans);
        final List<Short> encode = status.encode();
        for (int i = 0; i < encode.size(); i++) {
            short value = encode.get(i);
            basicProcessImage.setHoldingRegister(i + status.getOffset(), value);
        }
    }
}
